// Creation History:
//---------------------------------------------
// COMPANY : HTHK
// BY      : Zhiguo Yang
// Date    : 30/03/2005
// CRLOG   : P999
//---------------------------------------------
//
/*
 * Created on 2005-1-1
 *
 * $Id: SimpleScheduler.java,v 1.1.1.1 2013/08/16 05:35:48 tengyang Exp $
 * $Log: SimpleScheduler.java,v $
 * Revision 1.1.1.1  2013/08/16 05:35:48  tengyang
 * no message
 *
 * Revision 1.3  2005/03/31 02:53:43  zhyan
 * Change the file header
 *
 * Revision 1.2  2005/03/30 13:30:30  zhyan
 * Add the file header
 *
 * Revision 1.1  2005/03/28 08:05:50  zhyan
 * Add common Job scheduler
 *
 * Revision 1.1  2005/01/03 07:26:20  zhyan
 * Add first cut of simple scheduler.
 *
 *
 * Copyright Global Delivery China Center
 * Hewlett Packard Crop. 2005 All Rights Reserved
 */
package com.hp.gdcc.webframe.scheduler;

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.Iterator;
import java.util.Vector;

import org.apache.commons.digester.Digester;
import org.apache.log4j.Logger;
import org.quartz.CronTrigger;
import org.quartz.JobDataMap;
import org.quartz.JobDetail;
import org.quartz.Scheduler;
import org.quartz.SchedulerException;
import org.quartz.SchedulerFactory;
import org.quartz.impl.StdSchedulerFactory;
import org.xml.sax.SAXException;

/**
 * This is a simple scheduler, When start it will read the xml config
 * file and get the job information, then add jobs into the quartz
 * job scheduler. <br>
 *
 * Pleae refer to following sample <br>
 * <p><code>
 * &lt;jobs&gt; <br>
 * &lt;job jobName="testJob" groupName="testGroup" <br>
 *      cronExp="0/15/30/45 * * ? * * *" <br>
 *      jobClassName="com.hp.gdcc.shmidc.common.scheduler.FooJob" &gt; <br>
 * &lt;jobParam name="test1" value="value1" /&gt; <br>
 * &lt/job&gt <br>
 * &lt/jobs&gt <br>
 *
 * </code></p>
 * @author <a href="mailto:zhi-guo.yang@hp.com">Zhiguo Yang </a>
 *         <p>
 *         CopyRight HP GDCC 2004
 *         </p>
 */
public class SimpleScheduler {
  private File confFile;
  private Logger logger = Logger.getLogger(this.getClass());

  private SchedulerFactory sf = new StdSchedulerFactory();

  public SimpleScheduler() {
    confFile = new File("jobinfo.xml");
  }

  public SimpleScheduler(File confFile) {
    this.confFile = confFile;
  }

  public void startScheduler() {
    try {
      logger.debug("Start Job Scheduler...");
      Scheduler sched = sf.getScheduler();
      /*
       * Remove the previously job store. Although this may not required, as we
       * use RAMJobStore.
       */
      String[] groups = sched.getTriggerGroupNames();
      for (int i = 0; i < groups.length; i++) {
        String[] names = sched.getTriggerNames(groups[i]);
        for (int j = 0; j < names.length; j++)
          sched.unscheduleJob(names[j], groups[i]);
      }
      groups = sched.getJobGroupNames();
      for (int i = 0; i < groups.length; i++) {
        String[] names = sched.getJobNames(groups[i]);
        for (int j = 0; j < names.length; j++)
          sched.deleteJob(names[j], groups[i]);
      }
      logger.debug("Already clear all old jobs");

      /*
       * Read the job information from configration files.
       */
      Digester digester = setupDigester();
      Vector jobInfo = (Vector) digester.parse(this.confFile);
      logger.debug("Already read job info from config file");

      /*
       * Set Job to the scheduler.
       */
      Iterator jobIt = jobInfo.iterator();
      int i = 0;
      while (jobIt.hasNext()) {
        JobInfo jinfo = (JobInfo) jobIt.next();
        Class jobClass = Class.forName(jinfo.getJobClassName());
        JobDetail jobDetail = new JobDetail(jinfo.getJobName(),
                                            jinfo.getGroupName(), jobClass);
        Vector params = jinfo.getJobParams();
        if (params.size() > 0) {
          Iterator paramIt = params.iterator();
          JobDataMap paramMap = new JobDataMap();
          while (paramIt.hasNext()) {
            JobParam param = (JobParam) paramIt.next();
            paramMap.put(param.getName(), param.getValue());
          }
          jobDetail.setJobDataMap(paramMap);
        }

        CronTrigger cTrigger = new CronTrigger("Trigger" + i,
                                               "defaultGroup", jinfo.getCronExp());
        sched.scheduleJob(jobDetail, cTrigger);
        i++;
      }

      sched.start();

    }
    catch (SchedulerException ex) {
      logger.debug(ex, ex);
      logger.error(ex.toString());
    }
    catch (SAXException ex) {
      logger.debug(ex, ex);
      logger.error(ex.toString());
    }
    catch (IOException ex) {
      logger.debug(ex, ex);
      logger.error(ex.toString());
    }
    catch (ClassNotFoundException ex) {
      logger.debug(ex, ex);
      logger.error(ex.toString());
    }
    catch (ParseException ex) {
      logger.debug(ex, ex);
      logger.error(ex.toString());
    }

  }

  public void shutdownScheudler() {

    try {
      Scheduler sched = sf.getScheduler();
      sched.shutdown(true);
    }
    catch (SchedulerException e) {
      logger.debug(e, e);
      logger.error(e.toString());
    }

  }

  private Digester setupDigester() {
    Digester digester = new Digester();
    digester.addObjectCreate("jobs", Vector.class);
    digester.addObjectCreate("jobs/job", JobInfo.class);
    digester.addSetNext("jobs/job", "add");
    digester.addSetProperties("jobs/job", "jobName", "jobName");
    digester.addSetProperties("jobs/job", "groupName", "groupName");
    digester.addSetProperties("jobs/job", "cronExp", "cronExp");
    digester.addSetProperties("jobs/job", "jobClassName",
                              "jobClassName");
    digester.addObjectCreate("jobs/job/jobParam", JobParam.class);
    digester.addSetNext("jobs/job/jobParam", "addParam");
    digester.addSetProperties("jobs/job/jobParam", "name", "name");
    digester.addSetProperties("jobs/job/jobParam", "value", "value");
    return digester;
  }
}
